package dominio;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.uqbar.commons.model.ObservableUtils;
import org.uqbar.commons.utils.Observable;

@Observable
public class Planta implements Serializable{
	private String nombre = "Planta";
	private int puntosAtaque, puntosDefensa, vidaInicial;
	private boolean terrestre;
	
	private List<Mejora> mejorasDisponibles = new ArrayList<Mejora>();
	private List<Mejora> mejorasCompradas = new ArrayList<Mejora>() ;
	
	/**
	 * Crea una planta terrestre y los valores por parametro
	 * @param nombre: de la planta
	 * @param puntosATK
	 * @param puntosDEF
	 */
	public Planta(String nombre, int puntosATK, int puntosDEF) {
		this.nombre = nombre;
		this.puntosAtaque = puntosATK;
		this.puntosDefensa = puntosDEF;
		this.vidaInicial = puntosDEF;
	}
	
	/**
	 * Crea una planta que puede ser terrestre o acuatica
	 * @param nombre: de la planta
	 * @param puntosATK
	 * @param puntosDEF
	 * @param terrestre: en false si es acuatica
	 */
	public Planta(String nombre, int puntosATK, int puntosDEF, boolean terrestre) {	
		this.nombre = nombre;
		this.puntosAtaque = puntosATK;
		this.puntosDefensa = puntosDEF;
		this.vidaInicial = puntosDEF;
		this.terrestre = terrestre;
		
		this.addMejoraDisponible(new Mejora("Mejora 10 defensa",100, 0, 10));
		this.addMejoraDisponible(new Mejora("Mejora 10 ataque", 100, 10, 0));
	}
	
	/**
	 * Constructor Utilizado para clonar una planta
	 * @param prototype
	 */
	private Planta(Planta prototype){
		this.mejorasCompradas = prototype.getMejorasCompradas();
		this.mejorasDisponibles = prototype.getMejorasDisponibles();
		this.nombre = prototype.getNombre();
		this.puntosAtaque = prototype.getPuntosAtaque();
		this.puntosDefensa = prototype.getVidaInicial();
		this.terrestre = prototype.getTerrestre();
	}
	
	/**
	 * Retorna un clon de planta, mismos valores, distinta identidad.
	 * @return Planta
	 */
	public Planta makeClone(){
		Planta theClone = new Planta(this);
		return theClone;
	}

	/**
	 * Quita los puntos def pasados por parametro, se balancea a cero en caso de
	 * dar negativo.
	 * 
	 * @param ataque
	 */
	public void quitarPuntosDef(int ataque) {
		this.puntosDefensa = this.puntosDefensa - ataque;
		if (this.estaMuerta()) {
			this.puntosDefensa = 0;
		}
	}
	
	public void mejorar(Mejora mejora) {
		this.aumentarAtaqueYDefensa(mejora.getAtaque(), mejora.getDefensa());
		this.mejorasCompradas.add(mejora);
		this.mejorasDisponibles.remove(mejora);
		ObservableUtils.forceFirePropertyChanged(this, "mejorasCompradas", this.getMejorasCompradas());
		ObservableUtils.forceFirePropertyChanged(this, "mejorasDisponibles", this.getMejorasDisponibles());
	}

	public void mejorar(Mejora mejora, boolean flagForce) {
		this.aumentarAtaqueYDefensa(mejora.getAtaque(), mejora.getDefensa());
		this.mejorasCompradas.add(mejora);
		this.mejorasDisponibles.remove(mejora);
		if(flagForce){
			ObservableUtils.forceFirePropertyChanged(this, "mejorasCompradas", this.getMejorasCompradas());
			ObservableUtils.forceFirePropertyChanged(this, "mejorasDisponibles", this.getMejorasDisponibles());
		}
		
	}
	public void aumentarAtaqueYDefensa(int ataque, int defensa) {
		this.puntosAtaque += ataque;
		this.puntosDefensa += defensa;
	}
	
	public void addMejoraDisponible(Mejora mejora) {
		this.getMejorasDisponibles().add(mejora);
	}

	public boolean estaMuerta() {
		return this.puntosDefensa <= 0;
	}

	public boolean getTerrestre() {
		return this.terrestre;
	}

	public List<Mejora> getMejorasDisponibles() {
		return mejorasDisponibles;
	}

	public void setMejorasDisponibles(List<Mejora> mejorasDisponibles) {
		this.mejorasDisponibles = mejorasDisponibles;
	}

	public List<Mejora> getMejorasCompradas() {
		return mejorasCompradas;
	}

	public void setMejorasCompradas(List<Mejora> mejorasCompradas) {
		this.mejorasCompradas = mejorasCompradas;
	}

	public void cambiarTipo() {
		this.terrestre = ! this.terrestre;
		}

	public String getNombre() {
		return nombre;
	}

	public int getPuntosAtaque() {
		return puntosAtaque;
	}

	public void setPuntosAtaque(int puntosAtaque) {
		this.puntosAtaque = puntosAtaque;
	}

	public int getPuntosDefensa() {
		return puntosDefensa;
	}

	public void setPuntosDefensa(int puntosDefensa) {
		this.puntosDefensa = puntosDefensa;
	}
	
	public int getVidaInicial() {
		return vidaInicial;
	}
	public void setVidaInicial(int vidaInicial) {
		this.vidaInicial = vidaInicial;
	}
	
	@Override
	public String toString() {
		return getNombre();
	}

	public String getDescripcion() {
		return this.getNombre() +" - "+ (this.getTerrestre() ? "TERRESTRE" : "ACUATICA");
	}

	public String getDetalles() {
			return this.getPuntosAtaque() +" ATK - "+ this.getPuntosDefensa()+ " DEF";
	}
}
